local extension = Package("fengqi_mountain")
extension.extensionName = "aaa_fengqi"

local U = require "packages/utility/utility"

Fk:loadTranslationTable{
  ["fengqi_mountain"] = "山",
}


local zuoci = General(extension, "efengqi__zuoci", "qun", 3)

---@param player ServerPlayer
local addHuashenSkill = function(player, skillName)
  local room = player.room
  local skill = Fk.skills[skillName]
  if (not skill) or player:hasSkill(skill, true) or (skill.lordSkill and player.role ~= "lord")
  or (#skill.attachedKingdom > 0 and not table.contains(skill.attachedKingdom, player.kingdom)) then
    return
  end

  local huashen_skills = player:getMark("efengqi__soul_skills")
  if huashen_skills == 0 then huashen_skills = {} end
  table.insert(huashen_skills, skillName)
  room:setPlayerMark(player, "efengqi__soul_skills", huashen_skills)

  player:addFakeSkill(skill)
  player:prelightSkill(skill.name, true)
  skill:onAcquire(player, false)
end

---@param player ServerPlayer
local removeHuashenSkill = function(player, skillName)
  local room = player.room
  local skill = Fk.skills[skillName]

  local huashen_skills = player:getMark("efengqi__soul_skills")
  if huashen_skills == 0 then return end
  if not table.contains(huashen_skills, skillName) then
    return
  end
  table.removeOne(huashen_skills, skillName)
  room:setPlayerMark(player, "efengqi__soul_skills", huashen_skills)

  --[[
  if player:hasSkill(skillName) then -- FIXME: 预亮的bug，预亮技能会导致服务器为玩家直接添加技能
    player:loseSkill(Fk.skills[skillName])
  end
  player:doNotify("LoseSkill", json.encode{ player.id, skillName })

  if skill:isInstanceOf(TriggerSkill) or table.find(skill.related_skills,
    function(s) return s:isInstanceOf(TriggerSkill) end) then
    player:doNotify("LoseSkill", json.encode{ player.id, skillName, true })
  end
  --]]

  player:loseFakeSkill(skill)
  skill:onLose(player)
  player:setSkillUseHistory(skillName, 0, Player.HistoryPhase)
  player:setSkillUseHistory(skillName, 0, Player.HistoryTurn)
  player:setSkillUseHistory(skillName, 0, Player.HistoryRound)
  player:setSkillUseHistory(skillName, 0, Player.HistoryGame)
end

---@param player ServerPlayer
---@param general General
local function addHuashen(player, general)
  local room = player.room
  local glist = player:getTableMark("@&efengqi__soul")
  table.insertIfNeed(glist, general.name)
  room:setPlayerMark(player, "@&efengqi__soul", glist)

  for _, s in ipairs(general:getSkillNameList()) do
    addHuashenSkill(player, s)
  end
end

local banned_huashen = {
  "starsp__xiahoudun",  -- 原因：无敌
  "shichangshi",   -- 原因：变将与休整
  "godjiaxu", "zhangfei","rfenghou__huangzhong", "liyixiejing", "olz__wangyun", "yanyan", "duanjiong", "wolongfengchu", "wuanguo",
  "os__wangling", -- 原因：没有可用技能
  "os__xia__liubei", -- 原因：发动技能逻辑缺陷
}

---@param player ServerPlayer
---@param general_name string
local function removeHuashen(player, general_name)
  local room = player.room
  local glist = player:getMark("@&efengqi__soul")
  if glist == 0 then return end
  table.removeOne(glist, general_name)
  room:setPlayerMark(player, "@&efengqi__soul", #glist > 0 and glist or 0)

  local general = Fk.generals[general_name]
  for _, s in ipairs(general.skills) do
    removeHuashenSkill(player, s.name)
  end
  for _, sname in ipairs(general.other_skills) do
    removeHuashenSkill(player, sname)
  end
end


local function getNewSoul (player, n)
  if n < 1 then return end
  local room = player.room
  local exclude_list = table.map(room.players, function(p)
    return p.general
  end)
  table.insertTable(exclude_list, banned_huashen)
  for _, p in ipairs(room.players) do
    local deputy = p.deputyGeneral
    if deputy and deputy ~= "" then
      table.insert(exclude_list, deputy)
    end
  end
  local generals = table.random(room.general_pile, n)---@type string[]
  for _, g in ipairs(generals) do
    addHuashen(player, Fk.generals[g])
  end
end

local huashen = fk.CreateTriggerSkill{
  name = "efengqi__huashen",
  events = {fk.GameStart},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self)
  end,
  on_use = function (self, event, target, player, data)
    getNewSoul(player, 2)
  end,

  refresh_events = {fk.SkillEffect},
  can_refresh = function (self, event, target, player, data)
    return target == player and
      table.contains(player:getTableMark("efengqi__soul_skills"), data.name)
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    -- to add StatusSkill to every player's cilent
    for _, s in ipairs(data.related_skills) do
      if s:isInstanceOf(StatusSkill) then
        room.status_skills[s.class] = room.status_skills[s.class] or {}
        table.insertIfNeed(room.status_skills[s.class], s)
        room:doBroadcastNotify("AddSkill", json.encode{player.id, s.name})
      end
    end

    local owners = table.filter(player:getTableMark("@&efengqi__soul"), function (name)
      local general = Fk.generals[name]
      return table.contains(general:getSkillNameList(), data.name)
    end)
    if #owners == 0 then return end
    local removed = room:askForChoice(player, owners, self.name)
    room.logic:getCurrentEvent():addCleaner(function()
      removeHuashen(player, removed)
    end)
  end,

  on_lose = function (self, player, is_death)
    for _, g in ipairs(player:getTableMark("@&efengqi__soul")) do
      removeHuashen(player, g)
    end
    player.room:setPlayerMark(player, "@&efengqi__soul", 0)
  end,
}
zuoci:addSkill(huashen)

local xinsheng = fk.CreateTriggerSkill{
  name = "efengqi__xinsheng",
  events = {fk.TurnEnd},
  can_trigger = function(self, _, target, player, data)
    return player:hasSkill(self) and player:hasSkill(huashen, true)
  end,
  on_cost = function (self, event, target, player, data)
    if #player:getTableMark("@&efengqi__soul") < 2 then
      self.cost_data = nil
      return true
    else
      local result = player.room:askForCustomDialog(player, self.name,
      "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml", {
        player:getTableMark("@&efengqi__soul"),
        {"OK"},
        "#efengqi__xinsheng-recast",
        {"Cancel"},
        1,
        999
      })
      if result ~= "" then
        local reply = json.decode(result)
        self.cost_data = reply.cards
        return true
      end
    end
  end,
  on_use = function(self, _, target, player, data)
    local room = player.room
    local n = 0
    local removed = self.cost_data or {}
    if #removed > 0 then
      for _, g in ipairs(removed) do
        removeHuashen(player, g)
      end
      n = #removed
    else
      n = 2 - #player:getTableMark("@&efengqi__soul")
    end
    getNewSoul(player, n)
  end,
}
zuoci:addSkill(xinsheng)

Fk:loadTranslationTable{
  ["efengqi__zuoci"] = "左慈",
  ["#efengqi__zuoci"] = "变化仙人",

  ["efengqi__huashen"] = "化身",
  [":efengqi__huashen"] = "锁定技，游戏开始时，你随机将两张武将牌置于武将牌上，称为“魂”，你可以于对应时机发动“魂”的技能，然后于结算后移去此“魂”。",
  ["@&efengqi__soul"] = "魂",

  ["efengqi__xinsheng"] = "新生",
  [":efengqi__xinsheng"] = "每回合结束时，将“魂”补至2张，若你未获得，你可重铸任意张。",
  ["#efengqi__xinsheng-recast"] = "新生：你可以重铸任意张“魂”",

  ["$efengqi__huashen1"] = "哼，肉眼凡胎，岂能窥视仙人变幻？",
  ["$efengqi__huashen2"] = "万物苍生，幻化由心。",
  ["$efengqi__xinsheng1"] = "幻幻无穷，生生不息。",
  ["$efengqi__xinsheng2"] = "吐故纳新，师法天地。",
  ["~efengqi__zuoci"] = "腾云跨风，飞升太虚……",
}

local sunce = General:new(extension, "efengqi__sunce", "wu", 4)

local jiang = fk.CreateTriggerSkill{
  name = "efengqi__jiang",
  anim_type = "drawcard",
  events = {fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      ((data.card.trueName == "slash" and data.card.color == Card.Red) or data.card.name == "duel")
  end,
  on_cost = function (self, event, target, player, data)
    local prompt = "#efengqi__jiang-draw"
    local add = false
    if target ~= player and not table.contains(TargetGroup:getRealTargets(data.tos), player.id)
      and not target:isProhibited(player, data.card) then
      add = true
      prompt = "#efengqi__jiang-add::"..target.id..":"..data.card:toLogString()
    end
    if player.room:askForSkillInvoke(player, self.name, nil, prompt) then
      self.cost_data = add
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(1, self.name)
    if self.cost_data == true then
      table.insert(data, {player.id})
    end
  end,
}
sunce:addSkill(jiang)

local zhiba = fk.CreateTriggerSkill{
  name = "efengqi__zhiba",
  anim_type = "drawcard",
  events = {fk.EventPhaseChanging},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    if data.to == Player.Discard then
      return player:isKongcheng()
    elseif data.to == Player.Draw then
      if target == player then
        return table.find(player.room.alive_players, function (p)
          return player:canPindian(p)
        end) ~= nil
      else
        return target:canPindian(player)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    if data.to == Player.Discard then
      return player.room:askForSkillInvoke(target, self.name, nil, "#efengqi__zhiba-skipDiscard:"..player.id)
    else
      if target == player then
        local targets = table.filter(room:getOtherPlayers(player, false), function (p) return player:canPindian(p) end)
        if #targets == 0 then return false end
        local tos = player.room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "#efengqi__zhiba-choose", self.name, true)
        if #tos > 0 then
          self.cost_data = {tos = tos}
          return true
        end
      else
        return player.room:askForSkillInvoke(target, self.name, nil, "#efengqi__zhiba-skipDraw:"..player.id)
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if data.to == Player.Discard then
      player:drawCards(3, self.name)
    else
      local from, to
      if target == player then
        from, to = player, room:getPlayerById(self.cost_data.tos[1])
      else
        from, to = target, player
      end
      local pindian = from:pindian({to}, self.name)
      local winner = pindian.results[to.id].winner
      if winner and winner:isAlive() then
        winner:drawCards(3, self.name)
      end
    end
    target:skip(data.to)
    return true
  end,
}
sunce:addSkill(zhiba)

local hunzi = fk.CreateTriggerSkill{
  name = "efengqi__hunzi$",
  frequency = Skill.Wake,
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Start and
      player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  can_wake = function(self, event, target, player, data)
    return player.hp == 1
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local targets = table.filter(room:getAlivePlayers(), function(p) return p.kingdom ~= "wu" end)
    if #targets > 0 then
      room:doIndicate(player.id, table.map(targets, Util.IdMapper))
      for _, p in ipairs(targets) do
        if p.hp > 1 then
          room:loseHp(p, p.hp - 1, self.name)
        end
      end
    end
  end,
}
sunce:addSkill(hunzi)

Fk:loadTranslationTable{
  ["efengqi__sunce"] = "孙策",
  ["#efengqi__sunce"] = "江东的小霸王",
  ["cv:efengqi__sunce"] = "彭尧",
  ["illustrator:efengqi__sunce"] = "云涯M",
  ["designer:efengqi__sunce"] = "白驹&朱苦力",

  ["efengqi__jiang"] = "激昂",
  [":efengqi__jiang"] = "一名角色使用【决斗】或红色【杀】时，你可以摸一张牌，若其不为你，你成为目标。",
  ["#efengqi__jiang-draw"] = "激昂：你可以摸一张牌",
  ["#efengqi__jiang-add"] = "激昂：你可以摸一张牌，并成为%dest使用%arg的目标",

  ["efengqi__zhiba"] = "制霸",
  [":efengqi__zhiba"] = "若你：有手牌，你与其他角色可以跳过摸牌阶段与对方拼点，赢者摸三张牌；无手牌，一名角色可以跳过弃牌阶段令你摸三张牌。",
  ["#efengqi__zhiba-skipDiscard"] = "制霸：你可以跳过弃牌阶段，令 %src 摸三张牌。",
  ["#efengqi__zhiba-choose"] = "制霸：你可以跳过摸牌阶段，与一名角色拼点，赢者摸三张牌",
  ["#efengqi__zhiba-skipDraw"] = "制霸：你可以跳过摸牌阶段，与 %src 拼点，赢者摸三张牌",

  ["efengqi__hunzi"] = "魂姿",
  [":efengqi__hunzi"] = "主公技，觉醒技，准备阶段，若你的体力值为1，令非吴势力角色依次将体力值扣减至1。",

  ["$efengqi__jiang1"] = "吾乃江东小霸王孙伯符！",
  ["$efengqi__jiang2"] = "江东子弟，何惧于天下！",
  ["$efengqi__hunzi1"] = "父亲在上，魂佑江东；公瑾在旁，智定天下！",
  ["$efengqi__hunzi2"] = "愿承父志，与公瑾共谋天下！",
  ["$efengqi__zhiba1"] = "我若怕你，非孙伯符也！",
  ["$efengqi__zhiba2"] = "是友是敌，一探便知。",
  ["~efengqi__sunce"] = "内事不决问张昭，外事不决问周瑜……",
}

local godzhaoyun = General:new(extension, "efengqi__godzhaoyun", "god", 4)
Fk:loadTranslationTable{
  ["efengqi__godzhaoyun"] = "神赵云",
  ["#efengqi__godzhaoyun"] = "",
  ["illustrator:efengqi__godzhaoyun"] = "M云涯",
  ["designer:efengqi__godzhaoyun"] = "zzcclll朱苦力",
}

local longhun = fk.CreateViewAsSkill{
  name = "efengqi__longhun",
  prompt = "#efengqi__longhun",
  pattern = ".|.|.|.|.|basic",
  interaction = function(self, player)
    local tag = Fk:currentRoom():getBanner("FQLongHun")
    if tag == nil then return false end
    local choices = {}
    for _, t in ipairs(tag) do
      local name = t:split(":")[4]
      local card = Fk:cloneCard(name)
      if ((Fk.currentResponsePattern == nil and player:canUse(card)) or
      (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card))) then
        table.insertIfNeed(choices, t)
      end
    end
    if #choices == 0 then return false end
    return UI.ComboBox { choices = choices }
  end,
  card_filter = function(self, to_select, selected)
    if self.interaction.data == nil or #selected > 1 then return false end
    local card = Fk:getCardById(to_select)
    local t = string.split(self.interaction.data, ":")
    if string.find(t[#t], U.ConvertSuit(card.suit, "int", "icon")) then
      return #selected == 0 or card.suit == Fk:getCardById(selected[1]).suit
    end
  end,
  view_as = function(self, cards)
    if #cards ~= 2 or not self.interaction.data then return nil end
    local c = Fk:cloneCard(string.split(self.interaction.data, ":")[4])
    c.skillName = self.name
    c:addSubcards(cards)
    return c
  end,
  enabled_at_play = function(self, player)
    return table.find(U.getAllCardNames("b"), function (name)
      return player:canUse(Fk:cloneCard(name))
    end)
  end,
  enabled_at_response = function (self, player, response)
    return not response and #player:getCardIds("he") > 1
  end,
  on_acquire = function (self, player, is_start)
    local room = player.room
    if room:getBanner("FQLongHun") then return end
    local tag, map = {}, {}
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id, true)
      if card.type == Card.TypeBasic and not card.is_derived then
        map[card.name] = map[card.name] or {}
        table.insertIfNeed(map[card.name], U.ConvertSuit(card.suit, "int", "icon"))
      end
    end
    for _, name in ipairs(Fk.all_card_names) do
      if map[name] then
        table.insert(tag, "FQLongHun:::" .. name.. ":" .. table.concat(map[name], ""))
      end
    end
    room:setBanner("FQLongHun", tag)
  end,
}

local longhun_trigger = fk.CreateTriggerSkill{
  name = "#efengqi__longhun_trigger",
  anim_type = "drawcard",
  events = { fk.CardUsing },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(longhun.name) and data.card.suit == Card.NoSuit and player:isKongcheng()
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player:drawCards(4, longhun.name)
  end,
}
longhun:addRelatedSkill(longhun_trigger)
godzhaoyun:addSkill(longhun)


Fk:loadTranslationTable{
  ["efengqi__longhun"] = "龙魂",
  [":efengqi__longhun"] = "你可以将两张同花色的牌当游戏内存在该花色的基本牌使用。你使用的无花色牌带有《空巢：摸四张牌》。",
  ["#efengqi__longhun"] = "龙魂:将两张同花色的牌当游戏内存在该花色的基本牌使用",
  ["FQLongHun"] = "%arg[%arg2]",
  ["#efengqi__longhun_trigger"] = "龙魂",
}

local juejing = fk.CreateTriggerSkill{
  name = "efengqi__juejing",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = { fk.HpChanged },
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and (player.hp == 1 or (player.hp - data.num) == 1)
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(1, self.name)
  end,
}

local juejing_maxcards = fk.CreateMaxCardsSkill{
  name = "#efengqi__juejing_maxcards",
  correct_func = function(self, player)
    if player:hasSkill(juejing.name) and player.hp == 1 then
      return #player:getCardIds("e")
    end
  end,
}
juejing:addRelatedSkill(juejing_maxcards)
godzhaoyun:addSkill(juejing)

Fk:loadTranslationTable{
  ["efengqi__juejing"] = "绝境",
  [":efengqi__juejing"] = "锁定技，你进入或脱离残躯状态时，摸一张牌。你的装备区内的牌带有《残躯：手牌上限+1》。",
}

return extension
